enum AssetType{
    NONE='none',
    IMAGE='image',
    SOUND='sound',
    JSON='json',
    PLIST='plist',
    FNT='fnt'
}
export default class Loader{
    private _list:any[]=[]
    private _res:Map<string,any>=new Map()
    loadManifest(manifest:any[]|string|any,progress?:(loaded:number,total:number,evt:any)=>void):Promise<void>{
        return new Promise<void>((resolve,reject)=>{
            if(typeof manifest == 'string'){
                const item={id:this.getFileName(manifest),src:manifest}
                this.pretreatment(item)
                this._list.push(item)
            }else if(Array.isArray(manifest)){
                manifest.forEach((item:any)=>{
                    this.pretreatment(item)
                })
                this._list=manifest
            }else{
                this.pretreatment(manifest)
                this._list.push(manifest)
            }
            //
            let i=0,len=this._list.length
            const load=()=>{
                if(i<len){
                    const item=this._list[i]
                    //console.log(item.type)
                    switch(item.type){
                        case AssetType.IMAGE:
                            this.load_image(item.src).then((img:HTMLImageElement)=>{
                                //item.result=img
                                this._res.set(item.id,img)
                                i++
                                progress?.(i,len,{item:item,result:img})
                                load()
                            }).catch(reject)
                            break
                        case AssetType.SOUND:
                            this.load_sound(item.src).then((sound:HTMLAudioElement)=>{
                                this._res.set(item.id,sound)
                                i++
                                progress?.(i,len,{item:item,result:sound})
                                load()
                            }).catch(reject)
                            break
                        case AssetType.JSON:
                            this.load_json(item.src).then(res=>{
                                this._res.set(item.id,res)
                                i++
                                progress?.(i,len,{item:item,result:res})
                                load()
                            }).catch(reject)
                            /*wx.downloadFile({url:item.src,success:res=>{
                                if (res.statusCode === 200) {
                                    const fs = wx.getFileSystemManager()
                                    const json=fs.readFileSync(res.tempFilePath,'utf-8');
                                    //console.log(json)
                                    const data=JSON.parse(json as string)
                                    this._res.set(item.id,data)
                                    i++
                                    progress?.(i,len,{item:item,result:data})
                                    load()
                                }
                            },fail:err=>{
                                console.log(err)
                                reject()
                            }})*/
                    }
                    //
                }else{
                    resolve()
                }
            }
            load()
        })
    }
    getResource(id:string):any{
        return this._res.get(id)
    }
    getResult(id:string):any{
        return this._res.get(id)
    }
    private pretreatment(item:any):void{
        item.type=this.getAssetType(item.src)
    }
    //
    // private getAssetType(url:string):string{
    //     const n=url.lastSearch(/\.\w*/)
    //     switch(url.substring(n,url.length)){
    //         case '.jpg':
    //             return 'image'
    //         case '.png':
    //             return 'image'
    //         case '.mp3':
    //             return 'sound'
    //         case '.json':
    //             return 'json'
    //         case '.plist':
    //             return AssetType.PLIST
    //         case '.fnt':
    //             return AssetType.FNT
    //     }
    //     return 'none'
    // }
    private getAssetType(url:string):AssetType{
        const n=url.lastSearch(/\.\w*/)
        switch(url.substring(n,url.length)){
            case '.jpg':
            case '.png':
                return AssetType.IMAGE
            case '.mp3':
                return AssetType.SOUND
            case '.json':
                return AssetType.JSON
            case '.plist':
                return AssetType.PLIST
            case '.fnt':
                return AssetType.FNT
        }
        return AssetType.NONE
    }
    private getFileName(url:string):string{
        const n=url.lastSearch(/\/.*\.\w*/)
        return url.substring(n+1,url.length)
    }
    private load_image(url:string):Promise<HTMLImageElement>{
        return new Promise<HTMLImageElement>((resolve,reject)=>{
            const img=new Image()
            img.src=url
            img.onload=()=>{
                resolve(img)
            }
            img.onerror=()=>{
                reject()
            }
        })
    }
    private load_sound(url:string):Promise<HTMLAudioElement>{
        return new Promise<HTMLAudioElement>((resolve,reject)=>{
            const audio=new Audio()
            audio.src=url
            const onload=()=>{
                audio.removeEventListener('load',onload)
                audio.removeEventListener('error',onError)
                resolve(audio)
            }
            const onError=()=>{
                audio.removeEventListener('load',onload)
                audio.removeEventListener('error',onError)
                reject()
            }
            audio.addEventListener('load',onload)
            audio.addEventListener('error',onError)
        })
    }
    private load_json(url:string):Promise<any>{
        return new Promise<any>((resolve,reject)=>{
            if(url.substring(0,7)=='http://'||url.substring(0,8)=='https://'){
                wx.downloadFile({url,success:res=>{
                    if (res.statusCode === 200) {
                        const fs = wx.getFileSystemManager()
                        const json=fs.readFileSync(res.tempFilePath,'utf-8');
                        //console.log(json)
                        const data=JSON.parse(json as string)
                        resolve(data)
                        /*this._res.set(item.id,data)
                        i++
                        progress?.(i,len,{item:item,result:data})
                        load()*/
                    }
                },fail:err=>{
                    //console.log(err)
                    reject()
                }})
            }else{
            const fs = wx.getFileSystemManager();
            // 读取本地JSON文件
            fs.readFile({
                filePath: url, // 替换为你的JSON文件路径
                encoding: 'utf8', // 指定编码方式
                success: (res:any) => {
                // 解析JSON数据
                const jsonData = JSON.parse(res.data);
                resolve(jsonData)
                },
                fail: (err) => {
                    console.log('读取JSON文件失败:', err);
                    reject(err)
                }
            })}
        })
    }
}